#include "stdafx.h"
#include "XMLInstance.h"
#include "UtilInstance.h"
#include "libxml/HTMLtree.h"

CXMLInstance::CXMLInstance(char* str_filename)
{
	sprintf(m_str_filename, ("%s\\%s"), g_WorkDir, str_filename);
	xmlDoc = xmlParseFile(m_str_filename);

	if(!xmlDoc)
		rootNode = NULL;
	else
	{
		rootNode = xmlDocGetRootElement(xmlDoc);
		if(rootNode == NULL)
		{
			xmlFreeDoc(xmlDoc);
			xmlDoc = NULL;
		}
	}

	if(xmlDoc == NULL)
	{
		AfxMessageBox(_T("Server Config File is corrupted or is not exist."), NULL, NULL);
		ExitProcess(0);
	}
}

CXMLInstance::~CXMLInstance(void)
{
}

WCHAR* CXMLInstance::GetXmlElement(char* elementPath)
{
	xmlNodePtr node = FindXmlNode(elementPath);
	if(node == NULL)
		return NULL;

	char* result = (char*)node->content;

	if(result != NULL && strlen(result) == 0)
		return NULL;

	return CUtilInstance::GetInstance()->CharToWChar(result);
}

BOOL  CXMLInstance::SetXmlElement(char* elementPath, char* value)
{
	if(value == NULL)
		return FALSE;

	FILE* fp = NULL;

	xmlNodePtr node = FindXmlNode(elementPath);
	if(node == NULL)
		return FALSE;

	strcpy((char*)(node->content), value);
	return TRUE;
}

BOOL  CXMLInstance::SetXmlElement(char* elementPath, WCHAR* valuew)
{
	if(valuew == NULL)
		return FALSE;

	char* value = CUtilInstance::GetInstance()->WCharToChar(valuew);

	xmlNodePtr node = FindXmlNode(elementPath);
	if(node == NULL)
	{
		delete[] value;
		return FALSE;
	}

	strcpy((char*)(node->content), value);
	delete[] value;
	return TRUE;
}

BOOL  CXMLInstance::SetXmlElement(char* elementPath, int value)
{
	char valueStr[20];
	sprintf(valueStr, "%d", value);

	xmlNodePtr node = FindXmlNode(elementPath);
	if(node == NULL)
		return FALSE;

	strcpy((char*)(node->content), valueStr);
	return TRUE;
}

BOOL  CXMLInstance::SetXmlElement(char* elementPath, double value)
{
	char valueStr[20];
	sprintf(valueStr, "%e", value);

	xmlNodePtr node = FindXmlNode(elementPath);
	if(node == NULL)
		return FALSE;

	strcpy((char*)(node->content), valueStr);
	return TRUE;
}

BOOL  CXMLInstance::SaveXml()
{
	if (strlen(m_str_filename) > 0)
		xmlSaveFormatFile(m_str_filename, xmlDoc, 1);
	return TRUE;
}

xmlNodePtr CXMLInstance::FindXmlNode(char* elementPath)
{
	if(elementPath == NULL || strlen(elementPath) == 0 || rootNode == NULL)
		return NULL;

	char elemPath[500];
	strcpy(elemPath, elementPath);

	char* ptrTempPosition;
	char* token = strtok_u(elemPath, "/", &ptrTempPosition);
	if(strcmp(token, (char*)(rootNode->name)))
		return NULL;

	token = strtok_u(NULL, "/", &ptrTempPosition);
	if(token == NULL)
		return rootNode;

	xmlNodePtr cur = rootNode->xmlChildrenNode;
	if(cur == NULL)
		return NULL;

	if(cur->type == XML_TEXT_NODE)
		cur = cur->next;

	while(token != NULL)
	{
		while (cur != NULL)
		{
			if(cur->type == XML_TEXT_NODE)
			{
				cur = cur->next;
				continue;
			}

			if (!xmlStrcmp(cur->name, (const xmlChar *) token))
			{
				cur = cur->xmlChildrenNode;
				break;
			}

			cur = cur->next;
		}

		if(cur == NULL)
			return NULL;

		token = strtok_u(NULL, "/", &ptrTempPosition);
	}

	return cur;
}

int CXMLInstance::GetXmlElementInt(char* elementPath)
{
	xmlNodePtr node = FindXmlNode(elementPath);
	if(node == NULL)
		return NULL;

	char* result = (char*)node->content;

	if(result != NULL && strlen(result) == 0)
		return NULL;

	return strtol(result, NULL, 10);
}

double CXMLInstance::GetXmlElementDouble(char* elementPath)
{
	xmlNodePtr node = FindXmlNode(elementPath);
	if(node == NULL)
		return NULL;

	char* result = (char*)node->content;

	if(result != NULL && strlen(result) == 0)
		return NULL;

	return strtod(result, NULL);
}

WCHAR* CXMLInstance::GetXmlElementWChar(char* elementPath)
{
	xmlNodePtr node = FindXmlNode(elementPath);
	if(node == NULL)
		return NULL;

	char* result = (char*)node->content;

	if(result != NULL && strlen(result) == 0)
		return NULL;

	return CUtilInstance::GetInstance()->CharToWChar(result);
}

char* CXMLInstance::GetXmlElementChar(char* elementPath)
{
	xmlNodePtr node = FindXmlNode(elementPath);
	if(node == NULL)
		return NULL;

	char* result = (char*)node->content;

	if(result != NULL && strlen(result) == 0)
		return NULL;

	return result;
}

#ifndef LINUX_NAS
void CXMLInstance::GetXmlElementList(char* elementPath, CMap<int, int, CString, CString> &map)
{
	xmlNodePtr node = FindXmlNode(elementPath);
	if(node == NULL)
		return;

	if(node->type == XML_TEXT_NODE)
		node = node->next;

	int keyIndex = 0;
	//node = node->children;

	while (node != NULL)
	{
		if(node->type == XML_ELEMENT_NODE)
		{
			xmlNodePtr nodeChild = node->children;

			CString value;
			WCHAR* temp = CUtilInstance::GetInstance()->CharToWChar((char*)nodeChild->content);
			value.Format(_T("%s"), temp);	
			delete[] temp;
			map.SetAt(keyIndex, value);
			keyIndex++;
		}
		node = node->next;
	}
}
#else
void CXMLInstance::GetXmlElementList(char* elementPath, map<int, CString> &Map)
{
	typedef pair <int, CString> MAP_Pair;

	xmlNodePtr node = FindXmlNode(elementPath);
	if(node == NULL)
		return;

	if(node->type == XML_TEXT_NODE)
		node = node->next;

	int keyIndex = 0;
	//node = node->children;

	while (node != NULL)
	{
		if(node->type == XML_ELEMENT_NODE)
		{
			xmlNodePtr nodeChild = node->children;

			CString value;
			WCHAR* temp = CUtilInstance::GetInstance()->CharToWChar((char*)nodeChild->content);
			value.Format(_T("%S"), temp);	
			delete[] temp;
			//Map.SetAt(keyIndex, value);
			Map.insert(MAP_Pair(keyIndex, value));
			keyIndex++;
		}
		node = node->next;
	}
}

BOOL CXMLInstance::SetXmlElement(char* elementPath, const char* value)
{
	SetXmlElement(elementPath, (char*)value);
}
#endif